//===============================================================================
// Microsoft patterns & practices
// Smart Client Software Factory 2010
//===============================================================================
// Copyright (c) Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
//===============================================================================
//----------------------------------------------------------------------------------------
// patterns & practices - Smart Client Software Factory - Guidance Package
//
// This file was generated by the "Add CAB Module" recipe.
//
// This class contains placeholder methods for the common module initialization 
// tasks, such as adding services, or user-interface element
//
// For more information see: 
// // ms-help://MS.VSCC.v80/MS.VSIPCC.v80/ms.scsf.2006jun/SCSF/html/03-270-Creating%20a%20Module.htm
//
// Latest version of this Guidance Package: http://go.microsoft.com/fwlink/?LinkId=62182
//----------------------------------------------------------------------------------------

using System;
using System.Threading;
using GlobalBank.BranchSystems.Interface.Services;
using GlobalBank.BranchSystems.Module.Constants;
using GlobalBank.BranchSystems.Module.Views;
using GlobalBank.Infrastructure.Interface;
using GlobalBank.Infrastructure.Interface.BusinessEntities;
using Microsoft.Practices.CompositeUI;
using Microsoft.Practices.CompositeUI.Commands;
using Microsoft.Practices.CompositeUI.EventBroker;
using Microsoft.Practices.CompositeUI.SmartParts;

namespace GlobalBank.BranchSystems.Module
{
	public class ModuleController : WorkItemController
	{		
		[EventPublication(EventTopicNames.CustomerWorkItemCreated, PublicationScope.Global)]
		public event EventHandler<EventArgs<WorkItem>> CustomerWorkItemCreated;

		private IWorkspace BranchSystemsWorkspace
		{
			get { return WorkItem.Workspaces[WorkspaceNames.BranchSystemsWorkspace]; }
		}

		public override void Run()
		{
			ExecuteActions();
			ShowDefaultView();
		}

		private void ExecuteActions()
		{
			WorkItem.Items.AddNew<ModuleActions>();
			ActionCatalog.Execute(ActionNames.ShowCustomerQueueManagementView, WorkItem, this, null);
			ActionCatalog.Execute(ActionNames.ShowOfficerQueueView, WorkItem, this, null);
			ActionCatalog.Execute(ActionNames.ServiceCustomerAction, WorkItem, this, null);
			ActionCatalog.Execute(ActionNames.ShowAddVisitorToQueueCommand, WorkItem, this, null);
			ActionCatalog.Execute(ActionNames.ShowFindCustomerCommand, WorkItem, this, null);
		}

		private void ShowDefaultView()
		{
			DefaultView view = WorkItem.SmartParts.AddNew<DefaultView>();
			WorkItem.Workspaces[WorkspaceNames.BranchSystemsWorkspace].Show(view);
		}

		[CommandHandler(CommandNames.FindCustomer)]
		public void OnFindCustomer(object sender, EventArgs args)
		{
			ControlledWorkItem<FindCustomerController> findCustomerWorkItem =
				WorkItem.WorkItems.AddNew<ControlledWorkItem<FindCustomerController>>();
			findCustomerWorkItem.Controller.Run();
		}

		[CommandHandler(CommandNames.EnqueueVisitor)]
		public void OnEnqueueVisitor(object sender, EventArgs args)
		{
			IAddVisitorToQueueView view = WorkItem.SmartParts.AddNew<AddVisitorToQueueView>();
			WorkItem.Workspaces[WorkspaceNames.ModalWindows].Show(view);
		}

		[CommandHandler(CommandNames.ServiceCustomer)]
		public void ServiceCustomerCommandHandler(object sender, EventArgs e)
		{
			ICurrentQueueEntryService currentEntryService = WorkItem.Services.Get<ICurrentQueueEntryService>();
			ServiceCustomer(currentEntryService.CurrentEntry);
		}

		[EventSubscription(EventTopicNames.CustomerServicingChanged, ThreadOption.UserInterface)]
		public void CustomerServicingChangedHandler(object sender, EventArgs<QueueEntry> e)
		{
			ServiceCustomer(e.Data);
		}

		[EventSubscription(EventTopicNames.CustomerQueueUpdate, ThreadOption.UserInterface)]
		public void OnCustomerQueueIsEmpty(object sender, EventArgs<QueueEntry[]> eventArgs)
		{
			WorkItem.Commands.Get(CommandNames.ServiceCustomer).Status = eventArgs.Data.Length == 0
			                                                             	? CommandStatus.Disabled
			                                                             	: CommandStatus.Enabled;
		}

		private void ServiceCustomer(QueueEntry entry)
		{
			ICurrentQueueEntryService currentEntryService = WorkItem.Services.Get<ICurrentQueueEntryService>();
			currentEntryService.CurrentEntry = entry;
			AssignCustomerToServicing(entry);
			GetOrCreateEntryWorkItem(entry).Activate();
			ActionCatalog.Execute(ActionNames.ActivateOfficerQueueView, WorkItem, this, null);
		}

		private void AssignCustomerToServicing(QueueEntry entry)
		{
			ICustomerQueueService queueService = WorkItem.Services.Get<ICustomerQueueService>();
			queueService.AssignToServicing(entry, Thread.CurrentPrincipal.Identity.Name);
		}

		private WorkItem GetOrCreateEntryWorkItem(QueueEntry entry)
		{
			string workItemId = entry.QueueEntryID;
			ControlledWorkItem<CustomerWorkItemController> entryWorkItem = null;
			if (WorkItem.WorkItems.Contains(workItemId))
			{
				entryWorkItem = WorkItem.WorkItems.Get<ControlledWorkItem<CustomerWorkItemController>>(workItemId);
			}
			else
			{
				entryWorkItem = WorkItem.WorkItems.AddNew<ControlledWorkItem<CustomerWorkItemController>>(workItemId);
				entryWorkItem.Controller.Run(entry, BranchSystemsWorkspace);
				OnCustomerWorkItemCreated(entryWorkItem);
			}
			return entryWorkItem;
		}

		private void OnCustomerWorkItemCreated(ControlledWorkItem<CustomerWorkItemController> entryWorkItem)
		{
			if (CustomerWorkItemCreated != null)
				CustomerWorkItemCreated(this, new EventArgs<WorkItem>(entryWorkItem));
		}
	}
}
